// Mirrors.cpp: implementation of the CMirrors class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Mirrors.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMirrors::CMirrors( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice ),
												 m_pvbMirrosPod( NULL ),
												 m_piqMask( NULL )
{
	for( DWORD i = 0 ; i < 5 ; i++ )
		m_pvbRectangles[i] = NULL;

	for( i = 0 ; i < 2 ; i++ )
		m_ptrMirrors[i] = NULL;

	for( i = 0 ; i < 5 ; i++ )
		m_piqText[i] = NULL;

	try
	{
		LoadTexture( "mirrorborder.jpg" );
		LoadAlphaTexture( "fx.bmp" );
		LoadAlphaTexture( "text.bmp" );
		LoadTexture( "mirrorback.jpg" );
		LoadTexture( "particleb.jpg" );
		LoadTexture( "particler.jpg" );
		LoadAlphaTexture( "triangle.bmp" );
		LoadAlphaTexture( "alphamask.bmp" );
		LoadAlphaTexture( "ornament.bmp" );
	}
	catch( CTextureException )
	{		
		throw CSystemException( "unable to load textures" );
	}

	if( FAILED( m_pDevice->CreateVertexBuffer( 6*16*sizeof(LMULTITEXVERTEX), 0, FVF_LMULTITEXVERTEX, D3DPOOL_DEFAULT, &m_pvbMirrosPod ) ) )	
		throw CSystemException( "unable to create mirrors pod vertex buffer" );	

	if( FAILED( m_pDevice->CreateVertexBuffer( 4*sizeof(TLMULTITEXVERTEX), 0, FVF_TLMULTITEXVERTEX, D3DPOOL_DEFAULT, &m_pvbOrnament ) ) )	
		throw CSystemException( "unable to create ornament vertex buffer" );	
	
	for( i = 0 ; i < 5 ; i++ )
	{	
		if( FAILED( m_pDevice->CreateVertexBuffer( 6*102*sizeof(LVERTEX), 0, FVF_LVERTEX, D3DPOOL_DEFAULT, &m_pvbRectangles[i] ) ) )		
			throw CSystemException( "unable to create rectangles vertex buffer" );		
	}

	if( FAILED( m_pDevice->CreateVertexBuffer( 5*3*sizeof(LVERTEX), 0, FVF_LVERTEX, D3DPOOL_DEFAULT, &m_pvbTrinagles ) ) )	
		throw CSystemException( "unable to create triangles vertex buffer" );

	if( !m_psEnergy[0].Initialize( m_pDevice ) )	
		throw CSystemException( "unable to initialize particle system [0]" );	

	if( !m_psEnergy[1].Initialize( m_pDevice ) )	
		throw CSystemException( "unable to initialize particle system [1]" );	
	
	m_piqMask = new CImageQuad( m_pDevice );	
	m_piqMask->Resize( -1.0f, -1.0f, 640.0f, 480.0f );

	m_piqFlash = new CImageQuad( m_pDevice );

	m_piqFade = new CImageQuad( m_pDevice );
	m_bRenderFade = FALSE;

	m_ptrMirrors[0] = new CTextureRenderer( m_pDevice, FALSE, 512, 512 );
	m_ptrMirrors[1] = new CTextureRenderer( m_pDevice, FALSE, 512, 512 );	

	for( i = 0 ; i < 5 ; i++ )	
	{	
		m_piqText[i] = new CImageQuad( m_pDevice );
		m_piqText[i]->SetAlpha( 0x0 );
	}
	
	m_bRenderText = FALSE;

	m_dwCurrentPage = 0;

	PTLVERTEX				pV;

	m_piqText[0]->Lock( (LPBYTE*)&pV );

	pV[0].m_fU = 0.184f; pV[1].m_fU = 0.623f;	
	pV[2].m_fU = 0.184f; pV[3].m_fU = 0.184f;	
	pV[4].m_fU = 0.623f; pV[5].m_fU = 0.623f;		

	m_piqText[0]->Unlock();

	m_piqText[1]->Lock( (LPBYTE*)&pV );

	pV[0].m_fU = 0.768f; pV[1].m_fU = 1.000f;	
	pV[2].m_fU = 0.768f; pV[3].m_fU = 0.768f;	
	pV[4].m_fU = 1.000f; pV[5].m_fU = 1.000f;		

	m_piqText[1]->Unlock();

	m_piqText[2]->Lock( (LPBYTE*)&pV );

	pV[0].m_fU = 0.000f; pV[1].m_fU = 0.123f;	
	pV[2].m_fU = 0.000f; pV[3].m_fU = 0.000f;	
	pV[4].m_fU = 0.123f; pV[5].m_fU = 0.123f;		

	m_piqText[2]->Unlock();

	m_piqText[3]->Lock( (LPBYTE*)&pV );

	pV[0].m_fU = 0.623f; pV[1].m_fU = 0.768f;	
	pV[2].m_fU = 0.623f; pV[3].m_fU = 0.623f;	
	pV[4].m_fU = 0.768f; pV[5].m_fU = 0.768f;	

	m_piqText[3]->Unlock();

	m_piqText[4]->Lock( (LPBYTE*)&pV );

	pV[0].m_fU = 0.123f; pV[1].m_fU = 0.184f;	
	pV[2].m_fU = 0.123f; pV[3].m_fU = 0.123f;	
	pV[4].m_fU = 0.184f; pV[5].m_fU = 0.184f;

	m_piqText[4]->Unlock();

	PLVERTEX				pVertices;
	he3d_CMatrix			mtx;	
	FLOAT					fShift;

	FLOAT					fA, fB, fG;	

	for( i = 0 ; i < 5 ; i++ )
	{
		m_pvbRectangles[i]->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

		fA = 0.0f;
		fB = 0.0f;
		fG = 0.0f;

		for( DWORD j = 0 ; j < 10 ; j++ )
			for( DWORD k = 0 ; k < 10 ; k++ )
			{
				fA = (FLOAT)j*H_2PI/10.0f;
				fB = (FLOAT)(k+1)*H_PI/11.0f;

				mtx = XRotationMtx( fB )*YRotationMtx( fA );
				fShift = 2.0f*RAND();
			
				*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift,  4.5f )*mtx, 0x80000000, 0.0f, 0.0f );
				*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift, -4.5f )*mtx, 0x80000000, 0.0f, 1.0f );
				*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift, -4.5f )*mtx, 0x80000000, 1.0f, 1.0f );

				*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift, -4.5f )*mtx, 0x80000000, 1.0f, 1.0f );
				*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift,  4.5f )*mtx, 0x80000000, 1.0f, 0.0f );
				*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift,  4.5f )*mtx, 0x80000000, 0.0f, 0.0f );
			}		
		
		mtx = XRotationMtx( 0.0f )*YRotationMtx( 0.0f );
		fShift = 2.0f*RAND();

		*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift,  4.5f )*mtx, 0x0, 0.0f, 0.0f );
		*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift, -4.5f )*mtx, 0x0, 0.0f, 1.0f );
		*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift, -4.5f )*mtx, 0x0, 1.0f, 1.0f );

		*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift, -4.5f )*mtx, 0x0, 1.0f, 1.0f );
		*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift,  4.5f )*mtx, 0x0, 1.0f, 0.0f );
		*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift,  4.5f )*mtx, 0x0, 0.0f, 0.0f );

		mtx = XRotationMtx( H_PI )*YRotationMtx( 0.0f );
		fShift = 2.0f*RAND();

		*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift,  4.5f )*mtx, 0x0, 0.0f, 0.0f );
		*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift, -4.5f )*mtx, 0x0, 0.0f, 1.0f );
		*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift, -4.5f )*mtx, 0x0, 1.0f, 1.0f );

		*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift, -4.5f )*mtx, 0x0, 1.0f, 1.0f );
		*(pVertices++) = LVERTEX( he3d_CVector(  4.5f, 50.0f + fShift,  4.5f )*mtx, 0x0, 1.0f, 0.0f );
		*(pVertices++) = LVERTEX( he3d_CVector( -4.5f, 50.0f + fShift,  4.5f )*mtx, 0x0, 0.0f, 0.0f );

		m_pvbRectangles[i]->Unlock();
	}

	m_pvbTrinagles->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 5 ; i++ )
	{
		*(pVertices++) = LVERTEX( 0.0f, 0.0f, 0.0f, 0x0, 0.5f, 1.0f );
		*(pVertices++) = LVERTEX( 50.0f*cosf( (FLOAT)i*H_2PI*0.2f - 0.2f ), 50.0f*sinf( (FLOAT)i*H_2PI*0.2f - 0.2f ), -20.0f, 0x0, 0.0f, 0.0f );
		*(pVertices++) = LVERTEX( 50.0f*cosf( (FLOAT)i*H_2PI*0.2f + 0.2f ), 50.0f*sinf( (FLOAT)i*H_2PI*0.2f + 0.2f ), -20.0f, 0x0, 1.0f, 0.0f );
	}

	m_pvbTrinagles->Unlock();

	DWORD					dwIndex = 0;
	PLMULTITEXVERTEX		pVerts;
	
	m_pvbMirrosPod->Lock( 0, 0, (LPBYTE*)&pVerts, 0 );

	for( i = 0 ; i < 4 ; i++ )
		for( DWORD j = 0 ; j < 4 ; j++ )
		{					
			mtx = XRotationMtx( (FLOAT)(j+1)*H_PI/5.0f )*YRotationMtx( (FLOAT)i*H_2PI/4.0f );				

			*(pVerts++) = LMULTITEXVERTEX( he3d_CVector( -10.5f, 40.0f,  10.5f )*mtx, 0x0, (FLOAT)i*0.25f, (FLOAT)j*0.25f, 0.0f, 0.0f );
			*(pVerts++) = LMULTITEXVERTEX( he3d_CVector( -10.5f, 40.0f, -10.5f )*mtx, 0x0, (FLOAT)i*0.25f, (FLOAT)(j+1)*0.25f, 0.0f, 1.0f );
			*(pVerts++) = LMULTITEXVERTEX( he3d_CVector(  10.5f, 40.0f, -10.5f )*mtx, 0x0, (FLOAT)(i+1)*0.25f, (FLOAT)(j+1)*0.25f, 1.0f, 1.0f );

			*(pVerts++) = LMULTITEXVERTEX( he3d_CVector(  10.5f, 40.0f, -10.5f )*mtx, 0x0, (FLOAT)(i+1)*0.25f, (FLOAT)(j+1)*0.25f, 1.0f, 1.0f );
			*(pVerts++) = LMULTITEXVERTEX( he3d_CVector(  10.5f, 40.0f,  10.5f )*mtx, 0x0, (FLOAT)(i+1)*0.25f, (FLOAT)j*0.25f, 1.0f, 0.0f );
			*(pVerts++) = LMULTITEXVERTEX( he3d_CVector( -10.5f, 40.0f,  10.5f )*mtx, 0x0, (FLOAT)i*0.25f, (FLOAT)j*0.25f, 0.0f, 0.0f );

			m_vPosition[dwIndex++] = he3d_CVector( 0.0f, 40.0f, 0.0f )*mtx;
		}

	m_pvbMirrosPod->Unlock();	
	
	for( i = 0, dwIndex=0 ; i < 4 ; i++ )
		for( DWORD j = 0 ; j < 4 ; j++, dwIndex++ )
		{
			m_d3dvpMirrors[dwIndex].MinZ = 0.0f;
			m_d3dvpMirrors[dwIndex].MaxZ = 0.0f;

			m_d3dvpMirrors[dwIndex].Width = 128;
			m_d3dvpMirrors[dwIndex].Height = 128;

			m_d3dvpMirrors[dwIndex].X = 128*i;
			m_d3dvpMirrors[dwIndex].Y = 128*j;
		}

	// particle setup

	for( i = 0 ; i < 2 ; i++ )
	{	
		m_psEnergy[i].ConfigureGravity( G_VECTOR, he3d_CVector( 0.0f, 1.0f, 0.0f ), 0.0f );	
		m_psEnergy[i].SetCollision( C_OFF );
		m_psEnergy[i].SetTexture( GetTexture( "particle.bmp" ) );
	}

	he3d_CVector			vPos[5];

	for( i = 0 ; i < 5 ; i++ )
		vPos[i] = he3d_CVector( 1.0f*SIGNEDRAND(), 0.0f, 2.0f*SIGNEDRAND() );
	
	for( i = 0 ; i < 5 ; i++ )
	{
		m_peEmiter[i].SetEmiterPos( he3d_CVector( 0.0f, 1.0f, 0.0f ) + vPos[i] );
		m_peEmiter[i].SetEmiterDir( he3d_CVector( 0.0f, -1.0f, 0.0f ) );
		m_peEmiter[i].SetEmitAngle( 5.01f );
		m_peEmiter[i].SetEmitCount( 2, 0 );
		m_peEmiter[i].SetSize( 3.0f, 2.0f );
		m_peEmiter[i].SetVelocity( 3.0f, 2.0f );
		m_peEmiter[i].SetLifeTime( 5.0f, 2.0f );
		m_peEmiter[i].SetParticleType( PT_STANDARD );
		m_peEmiter[i].SetEmitInterval( 0.5f );

		m_psEnergy[0].AddEmiter( &m_peEmiter[i] );
	}

	for( i = 5 ; i < 10 ; i++ )
	{
		m_peEmiter[i].SetEmiterPos( he3d_CVector( 0.0f, -1.0f, 0.0f ) + vPos[i-5] );
		m_peEmiter[i].SetEmiterDir( he3d_CVector( 0.0f, 1.0f, 0.0f ) );
		m_peEmiter[i].SetEmitAngle( 2.01f );
		m_peEmiter[i].SetEmitCount( 2, 0 );
		m_peEmiter[i].SetSize( 3.0f, 2.0f );
		m_peEmiter[i].SetVelocity( 3.0f, 2.0f );
		m_peEmiter[i].SetLifeTime( 5.0f, 2.0f );
		m_peEmiter[i].SetParticleType( PT_STANDARD );
		m_peEmiter[i].SetEmitInterval( 0.5f );

		m_psEnergy[1].AddEmiter( &m_peEmiter[i] );
	}

	for( FLOAT fTime = 0.0f ; fTime < 20.0f ; fTime += 0.25f )
	{
		m_psEnergy[0].Update( fTime );
		m_psEnergy[1].Update( fTime );
	}

	//sync splines
	m_fSync[0][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[0][ 1] = FLOATKEY(  0.14f,  0.00f );
	m_fSync[0][ 2] = FLOATKEY(  0.28f,  1.00f );
	m_fSync[0][ 3] = FLOATKEY(  0.48f,  0.00f );
	m_fSync[0][ 4] = FLOATKEY(  2.51f,  0.00f );
	m_fSync[0][ 5] = FLOATKEY(  2.71f,  1.00f );
	m_fSync[0][ 6] = FLOATKEY(  2.83f,  0.00f );
	m_fSync[0][ 7] = FLOATKEY(  2.94f,  1.00f );
	m_fSync[0][ 8] = FLOATKEY(  3.14f,  0.00f );
	m_fSync[0][ 9] = FLOATKEY(  4.32f,  0.00f );
	m_fSync[0][10] = FLOATKEY(  4.52f,  1.00f );
	m_fSync[0][11] = FLOATKEY(  4.72f,  0.00f );
	m_fSync[0][12] = FLOATKEY(  5.40f,  0.00f );
	m_fSync[0][13] = FLOATKEY(  5.60f,  1.00f );
	m_fSync[0][14] = FLOATKEY(  5.80f,  0.00f );
	m_fSync[0][15] = FLOATKEY(  5.92f,  0.00f );
	m_fSync[0][16] = FLOATKEY(  6.12f,  1.00f );
	m_fSync[0][17] = FLOATKEY(  6.32f,  0.00f );
	m_fSync[0][18] = FLOATKEY(  6.55f,  0.00f );
	m_fSync[0][19] = FLOATKEY(  6.75f,  1.00f );
	m_fSync[0][20] = FLOATKEY(  6.95f,  0.00f );
	m_fSync[0][21] = FLOATKEY(  7.22f,  0.00f );
	m_fSync[0][22] = FLOATKEY(  7.42f,  1.00f );
	m_fSync[0][23] = FLOATKEY(  7.62f,  0.00f );
	m_fSync[0][24] = FLOATKEY(  8.36f,  0.00f );
	m_fSync[0][25] = FLOATKEY(  8.56f,  1.00f );
	m_fSync[0][26] = FLOATKEY(  8.76f,  0.00f );
	m_fSync[0][27] = FLOATKEY(  9.01f,  0.00f );
	m_fSync[0][28] = FLOATKEY(  9.21f,  1.00f );
	m_fSync[0][29] = FLOATKEY(  9.41f,  0.00f );
	m_fSync[0][30] = FLOATKEY( 11.79f,  0.00f );
	m_fSync[0][31] = FLOATKEY( 11.99f,  1.00f );
	m_fSync[0][32] = FLOATKEY( 12.19f,  0.00f );
	m_fSync[0][33] = FLOATKEY( 12.47f,  0.00f );
	m_fSync[0][34] = FLOATKEY( 12.67f,  1.00f );
	m_fSync[0][35] = FLOATKEY( 12.87f,  0.00f );
	m_fSync[0][36] = FLOATKEY( 14.39f,  0.00f );
	m_fSync[0][37] = FLOATKEY( 14.59f,  1.00f );
	m_fSync[0][38] = FLOATKEY( 14.79f,  0.00f );
	m_fSync[0][39] = FLOATKEY( 15.10f,  0.00f );
	m_fSync[0][40] = FLOATKEY( 15.30f,  1.00f );
	m_fSync[0][41] = FLOATKEY( 15.50f,  0.00f );
	m_fSync[0][42] = FLOATKEY( 16.18f,  0.00f );
	m_fSync[0][43] = FLOATKEY( 16.38f,  1.00f );
	m_fSync[0][44] = FLOATKEY( 16.58f,  0.00f );
	m_fSync[0][45] = FLOATKEY( 17.39f,  0.00f );
	m_fSync[0][46] = FLOATKEY( 17.59f,  1.00f );
	m_fSync[0][47] = FLOATKEY( 17.70f,  0.00f );
	m_fSync[0][48] = FLOATKEY( 17.82f,  1.00f );
	m_fSync[0][49] = FLOATKEY( 17.92f,  0.00f );
	m_fSync[0][50] = FLOATKEY( 18.02f,  1.00f );
	m_fSync[0][51] = FLOATKEY( 18.14f,  0.00f );
	m_fSync[0][52] = FLOATKEY( 18.25f,  1.00f );
	m_fSync[0][53] = FLOATKEY( 18.38f,  0.00f );
	m_fSync[0][54] = FLOATKEY( 18.50f,  1.00f );
	m_fSync[0][55] = FLOATKEY( 18.70f,  0.00f );
	m_fSync[0][56] = FLOATKEY( 19.87f,  0.00f );
	m_fSync[0][57] = FLOATKEY( 20.07f,  1.00f );
	m_fSync[0][58] = FLOATKEY( 20.27f,  0.00f );
	m_fSync[0][59] = FLOATKEY( 20.44f,  0.00f );
	m_fSync[0][60] = FLOATKEY( 20.64f,  1.00f );
	m_fSync[0][61] = FLOATKEY( 20.84f,  0.00f );
	m_fSync[0][62] = FLOATKEY( 22.51f,  0.00f );
	m_fSync[0][63] = FLOATKEY( 22.71f,  1.00f );
	m_fSync[0][64] = FLOATKEY( 22.91f,  0.00f );
	m_fSync[0][65] = FLOATKEY( 23.20f,  0.00f );
	m_fSync[0][66] = FLOATKEY( 23.40f,  1.00f );
	m_fSync[0][67] = FLOATKEY( 23.60f,  0.00f );


	InitFloatSpline( 68, m_fSync[0] );

	m_fSync[1][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[1][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[1][ 2] = FLOATKEY(  1.19f,  0.00f );
	m_fSync[1][ 3] = FLOATKEY(  1.39f,  1.00f );
	m_fSync[1][ 4] = FLOATKEY(  1.49f,  0.00f );
	m_fSync[1][ 5] = FLOATKEY(  1.60f,  1.00f );
	m_fSync[1][ 6] = FLOATKEY(  1.80f,  0.00f );
	m_fSync[1][ 7] = FLOATKEY(  3.17f,  0.00f );
	m_fSync[1][ 8] = FLOATKEY(  3.38f,  1.00f );
	m_fSync[1][ 9] = FLOATKEY(  3.51f,  0.00f );
	m_fSync[1][10] = FLOATKEY(  3.64f,  1.00f );
	m_fSync[1][11] = FLOATKEY(  3.81f,  0.00f );
	m_fSync[1][12] = FLOATKEY(  3.97f,  1.00f );
	m_fSync[1][13] = FLOATKEY(  4.13f,  0.00f );
	m_fSync[1][14] = FLOATKEY(  4.29f,  1.00f );
	m_fSync[1][15] = FLOATKEY(  4.49f,  0.00f );
	m_fSync[1][16] = FLOATKEY(  4.76f,  0.00f );
	m_fSync[1][17] = FLOATKEY(  4.96f,  1.00f );
	m_fSync[1][18] = FLOATKEY(  5.16f,  0.00f );
	m_fSync[1][19] = FLOATKEY(  7.69f,  0.00f );
	m_fSync[1][20] = FLOATKEY(  7.89f,  1.00f );
	m_fSync[1][21] = FLOATKEY(  8.09f,  0.00f );
	m_fSync[1][22] = FLOATKEY(  9.69f,  0.00f );
	m_fSync[1][23] = FLOATKEY(  9.89f,  1.00f );
	m_fSync[1][24] = FLOATKEY( 10.09f,  0.00f );
	m_fSync[1][25] = FLOATKEY( 10.61f,  0.00f );
	m_fSync[1][26] = FLOATKEY( 10.81f,  1.00f );
	m_fSync[1][27] = FLOATKEY( 11.01f,  0.00f );
	m_fSync[1][28] = FLOATKEY( 11.41f,  0.00f );
	m_fSync[1][29] = FLOATKEY( 11.61f,  1.00f );
	m_fSync[1][30] = FLOATKEY( 11.81f,  0.00f );
	m_fSync[1][31] = FLOATKEY( 13.33f,  0.00f );
	m_fSync[1][32] = FLOATKEY( 13.53f,  1.00f );
	m_fSync[1][33] = FLOATKEY( 13.73f,  0.00f );
	m_fSync[1][34] = FLOATKEY( 13.78f,  0.00f );
	m_fSync[1][35] = FLOATKEY( 13.98f,  1.00f );
	m_fSync[1][36] = FLOATKEY( 14.08f,  0.00f );
	m_fSync[1][37] = FLOATKEY( 14.19f,  1.00f );
	m_fSync[1][38] = FLOATKEY( 14.39f,  0.00f );
	m_fSync[1][39] = FLOATKEY( 15.55f,  0.00f );
	m_fSync[1][40] = FLOATKEY( 15.75f,  1.00f );
	m_fSync[1][41] = FLOATKEY( 15.88f,  0.00f );
	m_fSync[1][42] = FLOATKEY( 16.01f,  1.00f );
	m_fSync[1][43] = FLOATKEY( 16.22f,  0.00f );
	m_fSync[1][44] = FLOATKEY( 16.94f,  0.00f );
	m_fSync[1][45] = FLOATKEY( 17.14f,  1.00f );
	m_fSync[1][46] = FLOATKEY( 17.34f,  0.00f );
	m_fSync[1][47] = FLOATKEY( 18.73f,  0.00f );
	m_fSync[1][48] = FLOATKEY( 18.93f,  1.00f );
	m_fSync[1][49] = FLOATKEY( 19.13f,  0.00f );
	m_fSync[1][50] = FLOATKEY( 19.14f,  0.00f );
	m_fSync[1][51] = FLOATKEY( 19.34f,  1.00f );
	m_fSync[1][52] = FLOATKEY( 19.54f,  0.00f );
	m_fSync[1][53] = FLOATKEY( 20.95f,  0.00f );
	m_fSync[1][54] = FLOATKEY( 21.15f,  1.00f );
	m_fSync[1][55] = FLOATKEY( 21.35f,  0.00f );
	m_fSync[1][56] = FLOATKEY( 21.65f,  0.00f );
	m_fSync[1][57] = FLOATKEY( 21.85f,  1.00f );
	m_fSync[1][58] = FLOATKEY( 22.05f,  0.00f );
	m_fSync[1][59] = FLOATKEY( 22.18f,  0.00f );
	m_fSync[1][60] = FLOATKEY( 22.38f,  1.00f );
	m_fSync[1][61] = FLOATKEY( 22.58f,  0.00f );


	InitFloatSpline( 62, m_fSync[1] );

	m_fSync[2][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[2][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[2][ 2] = FLOATKEY(  0.74f,  0.00f );
	m_fSync[2][ 3] = FLOATKEY(  0.94f,  1.00f );
	m_fSync[2][ 4] = FLOATKEY(  1.14f,  0.00f );
	m_fSync[2][ 5] = FLOATKEY(  1.88f,  0.00f );
	m_fSync[2][ 6] = FLOATKEY(  2.08f,  1.00f );
	m_fSync[2][ 7] = FLOATKEY(  2.28f,  0.00f );
	m_fSync[2][ 8] = FLOATKEY( 19.23f,  0.00f );
	m_fSync[2][ 9] = FLOATKEY( 19.43f,  1.00f );
	m_fSync[2][10] = FLOATKEY( 19.54f,  0.00f );
	m_fSync[2][11] = FLOATKEY( 19.64f,  1.00f );
	m_fSync[2][12] = FLOATKEY( 19.75f,  0.00f );
	m_fSync[2][13] = FLOATKEY( 19.86f,  1.00f );
	m_fSync[2][14] = FLOATKEY( 20.06f,  0.00f );


	InitFloatSpline( 15, m_fSync[2] );

	m_fSync[3][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[3][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[3][ 2] = FLOATKEY(  0.92f,  0.00f );
	m_fSync[3][ 3] = FLOATKEY(  1.12f,  1.00f );
	m_fSync[3][ 4] = FLOATKEY(  1.32f,  0.00f );
	m_fSync[3][ 5] = FLOATKEY(  1.62f,  0.00f );
	m_fSync[3][ 6] = FLOATKEY(  1.82f,  1.00f );
	m_fSync[3][ 7] = FLOATKEY(  2.02f,  0.00f );
	m_fSync[3][ 8] = FLOATKEY(  7.86f,  0.00f );
	m_fSync[3][ 9] = FLOATKEY(  8.06f,  1.00f );
	m_fSync[3][10] = FLOATKEY(  8.26f,  0.00f );
	m_fSync[3][11] = FLOATKEY( 10.20f,  0.00f );
	m_fSync[3][12] = FLOATKEY( 10.40f,  1.00f );
	m_fSync[3][13] = FLOATKEY( 10.51f,  0.00f );
	m_fSync[3][14] = FLOATKEY( 10.61f,  1.00f );
	m_fSync[3][15] = FLOATKEY( 10.81f,  0.00f );
	m_fSync[3][16] = FLOATKEY( 10.84f,  0.00f );
	m_fSync[3][17] = FLOATKEY( 11.04f,  1.00f );
	m_fSync[3][18] = FLOATKEY( 11.24f,  0.00f );
	m_fSync[3][19] = FLOATKEY( 11.29f,  0.00f );
	m_fSync[3][20] = FLOATKEY( 11.49f,  1.00f );
	m_fSync[3][21] = FLOATKEY( 11.59f,  0.00f );
	m_fSync[3][22] = FLOATKEY( 11.69f,  1.00f );
	m_fSync[3][23] = FLOATKEY( 11.89f,  0.00f );
	m_fSync[3][24] = FLOATKEY( 13.13f,  0.00f );
	m_fSync[3][25] = FLOATKEY( 13.33f,  1.00f );
	m_fSync[3][26] = FLOATKEY( 13.52f,  0.00f );
	m_fSync[3][27] = FLOATKEY( 13.71f,  1.00f );
	m_fSync[3][28] = FLOATKEY( 13.91f,  0.00f );
	m_fSync[3][29] = FLOATKEY( 17.16f,  0.00f );
	m_fSync[3][30] = FLOATKEY( 17.36f,  1.00f );
	m_fSync[3][31] = FLOATKEY( 17.56f,  0.00f );
	m_fSync[3][32] = FLOATKEY( 18.90f,  0.00f );
	m_fSync[3][33] = FLOATKEY( 19.10f,  1.00f );
	m_fSync[3][34] = FLOATKEY( 19.30f,  0.00f );
	m_fSync[3][35] = FLOATKEY( 20.76f,  0.00f );
	m_fSync[3][36] = FLOATKEY( 20.96f,  1.00f );
	m_fSync[3][37] = FLOATKEY( 21.16f,  0.00f );
	m_fSync[3][38] = FLOATKEY( 21.20f,  0.00f );
	m_fSync[3][39] = FLOATKEY( 21.40f,  1.00f );
	m_fSync[3][40] = FLOATKEY( 21.51f,  0.00f );
	m_fSync[3][41] = FLOATKEY( 21.61f,  1.00f );
	m_fSync[3][42] = FLOATKEY( 21.81f,  0.00f );


	InitFloatSpline( 43, m_fSync[3] );

	m_fSync[4][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[4][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[4][ 2] = FLOATKEY(  0.23f,  0.00f );
	m_fSync[4][ 3] = FLOATKEY(  0.43f,  1.00f );
	m_fSync[4][ 4] = FLOATKEY(  0.54f,  0.00f );
	m_fSync[4][ 5] = FLOATKEY(  0.66f,  1.00f );
	m_fSync[4][ 6] = FLOATKEY(  0.86f,  0.00f );
	m_fSync[4][ 7] = FLOATKEY(  2.18f,  0.00f );
	m_fSync[4][ 8] = FLOATKEY(  2.38f,  1.00f );
	m_fSync[4][ 9] = FLOATKEY(  2.44f,  0.00f );
	m_fSync[4][10] = FLOATKEY(  2.51f,  1.00f );
	m_fSync[4][11] = FLOATKEY(  2.71f,  0.00f );
	m_fSync[4][12] = FLOATKEY(  9.52f,  0.00f );
	m_fSync[4][13] = FLOATKEY(  9.72f,  1.00f );
	m_fSync[4][14] = FLOATKEY(  9.92f,  0.00f );
	m_fSync[4][15] = FLOATKEY( 12.62f,  0.00f );
	m_fSync[4][16] = FLOATKEY( 12.82f,  1.00f );
	m_fSync[4][17] = FLOATKEY( 13.02f,  0.00f );
	m_fSync[4][18] = FLOATKEY( 14.87f,  0.00f );
	m_fSync[4][19] = FLOATKEY( 15.07f,  1.00f );
	m_fSync[4][20] = FLOATKEY( 15.27f,  0.00f );
	m_fSync[4][21] = FLOATKEY( 16.01f,  0.00f );
	m_fSync[4][22] = FLOATKEY( 16.21f,  1.00f );
	m_fSync[4][23] = FLOATKEY( 16.41f,  0.00f );
	m_fSync[4][24] = FLOATKEY( 18.51f,  0.00f );
	m_fSync[4][25] = FLOATKEY( 18.71f,  1.00f );
	m_fSync[4][26] = FLOATKEY( 18.91f,  0.00f );
	m_fSync[4][27] = FLOATKEY( 20.32f,  0.00f );
	m_fSync[4][28] = FLOATKEY( 20.52f,  1.00f );
	m_fSync[4][29] = FLOATKEY( 20.62f,  0.00f );
	m_fSync[4][30] = FLOATKEY( 20.72f,  1.00f );
	m_fSync[4][31] = FLOATKEY( 20.92f,  0.00f );
	m_fSync[4][32] = FLOATKEY( 22.06f,  0.00f );
	m_fSync[4][33] = FLOATKEY( 22.26f,  1.00f );
	m_fSync[4][34] = FLOATKEY( 22.35f,  0.00f );
	m_fSync[4][35] = FLOATKEY( 22.44f,  1.00f );
	m_fSync[4][36] = FLOATKEY( 22.64f,  0.00f );


	InitFloatSpline( 37, m_fSync[4] );

	m_fSync[5][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[5][ 1] = FLOATKEY(  0.03f,  0.00f );
	m_fSync[5][ 2] = FLOATKEY(  0.06f,  1.00f );
	m_fSync[5][ 3] = FLOATKEY(  0.26f,  0.00f );
	m_fSync[5][ 4] = FLOATKEY(  2.96f,  0.00f );
	m_fSync[5][ 5] = FLOATKEY(  3.16f,  1.00f );
	m_fSync[5][ 6] = FLOATKEY(  3.36f,  0.00f );
	m_fSync[5][ 7] = FLOATKEY(  3.64f,  0.00f );
	m_fSync[5][ 8] = FLOATKEY(  3.84f,  1.00f );
	m_fSync[5][ 9] = FLOATKEY(  4.04f,  0.00f );
	m_fSync[5][10] = FLOATKEY(  4.98f,  0.00f );
	m_fSync[5][11] = FLOATKEY(  5.18f,  1.00f );
	m_fSync[5][12] = FLOATKEY(  5.30f,  0.00f );
	m_fSync[5][13] = FLOATKEY(  5.43f,  1.00f );
	m_fSync[5][14] = FLOATKEY(  5.63f,  0.00f );
	m_fSync[5][15] = FLOATKEY(  6.14f,  0.00f );
	m_fSync[5][16] = FLOATKEY(  6.34f,  1.00f );
	m_fSync[5][17] = FLOATKEY(  6.54f,  0.00f );
	m_fSync[5][18] = FLOATKEY(  6.82f,  0.00f );
	m_fSync[5][19] = FLOATKEY(  7.02f,  1.00f );
	m_fSync[5][20] = FLOATKEY(  7.10f,  0.00f );
	m_fSync[5][21] = FLOATKEY(  7.19f,  1.00f );
	m_fSync[5][22] = FLOATKEY(  7.39f,  0.00f );
	m_fSync[5][23] = FLOATKEY(  8.58f,  0.00f );
	m_fSync[5][24] = FLOATKEY(  8.78f,  1.00f );
	m_fSync[5][25] = FLOATKEY(  8.91f,  0.00f );
	m_fSync[5][26] = FLOATKEY(  9.04f,  1.00f );
	m_fSync[5][27] = FLOATKEY(  9.24f,  0.00f );
	m_fSync[5][28] = FLOATKEY( 11.94f,  0.00f );
	m_fSync[5][29] = FLOATKEY( 12.14f,  1.00f );
	m_fSync[5][30] = FLOATKEY( 12.30f,  0.00f );
	m_fSync[5][31] = FLOATKEY( 12.45f,  1.00f );
	m_fSync[5][32] = FLOATKEY( 12.65f,  0.00f );
	m_fSync[5][33] = FLOATKEY( 14.22f,  0.00f );
	m_fSync[5][34] = FLOATKEY( 14.42f,  1.00f );
	m_fSync[5][35] = FLOATKEY( 14.62f,  0.00f );
	m_fSync[5][36] = FLOATKEY( 15.33f,  0.00f );
	m_fSync[5][37] = FLOATKEY( 15.53f,  1.00f );
	m_fSync[5][38] = FLOATKEY( 15.73f,  0.00f );
	m_fSync[5][39] = FLOATKEY( 16.73f,  0.00f );
	m_fSync[5][40] = FLOATKEY( 16.93f,  1.00f );
	m_fSync[5][41] = FLOATKEY( 17.13f,  0.00f );
	m_fSync[5][42] = FLOATKEY( 22.76f,  0.00f );
	m_fSync[5][43] = FLOATKEY( 22.96f,  1.00f );
	m_fSync[5][44] = FLOATKEY( 23.08f,  0.00f );
	m_fSync[5][45] = FLOATKEY( 23.21f,  1.00f );
	m_fSync[5][46] = FLOATKEY( 23.41f,  0.00f );


	InitFloatSpline( 47, m_fSync[5] );


	m_dwKeyCount[0] = 68;
	m_dwKeyCount[1] = 62;
	m_dwKeyCount[2] = 15;
	m_dwKeyCount[3] = 43;
	m_dwKeyCount[4] = 37;
	m_dwKeyCount[5] = 47;

}

CMirrors::~CMirrors()
{
	SAFE_RELEASE( m_pvbMirrosPod );	

	for( DWORD i = 0 ; i < 5 ; i++ )
		SAFE_RELEASE( m_pvbRectangles[i] );

	SAFE_DELETE( m_piqMask );
	SAFE_DELETE( m_piqFade );
	SAFE_DELETE( m_piqFlash );

	for( i = 0 ; i < 2 ; i++ )
		SAFE_DELETE( m_ptrMirrors[i] );

	for( i = 0 ; i < 5 ; i++ )
		SAFE_DELETE( m_piqText[i] );
}

BOOL CMirrors::UpdateFrame( FLOAT fTime )
{

	FLOAT					fSync[6];

	for( DWORD i = 0 ; i < 6 ; i++ )
		fSync[i] = GetFloatSplineValue( fTime, m_dwKeyCount[i], m_fSync[i] );

	m_mtxRectangles[0] = ScaleMtx( 0.5f*fSync[0] + 1.0f )*RotationMtx( 0.25f*fTime, -0.15f*fTime, -0.2f*fTime );
	m_mtxRectangles[1] = ScaleMtx( 0.5f*fSync[1] + 1.0f )*RotationMtx( -0.25f*fTime, 0.25f*fTime,  0.1f*fTime );
	m_mtxRectangles[2] = ScaleMtx( 0.5f*fSync[2] + 1.0f )*RotationMtx( 0.2f*fTime,  0.1f*fTime, 0.25f*fTime );
	m_mtxRectangles[3] = ScaleMtx( 0.5f*fSync[3] + 1.0f )*RotationMtx( -0.15f*fTime, -0.25f*fTime, -0.15f*fTime );
	m_mtxRectangles[4] = ScaleMtx( 0.5f*fSync[4] + 1.0f )*RotationMtx( -0.2f*fTime, -0.1f*fTime, -0.25f*fTime );

	m_mtxTriangles[0] = ScaleMtx( 1.0f )*ZRotationMtx( 0.2f*fTime );
	m_mtxTriangles[1] = ScaleMtx( 1.1f )*ZRotationMtx( 0.3f*fTime );
	m_mtxTriangles[2] = ScaleMtx( 1.2f )*ZRotationMtx( 0.15f*fTime );
	m_mtxTriangles[3] = ScaleMtx( 1.3f )*ZRotationMtx( -0.2f*fTime );
	m_mtxTriangles[4] = ScaleMtx( 1.4f )*ZRotationMtx( -0.1f*fTime );

	m_mtxMirrors = RotationMtx( 0.45f*fTime, -0.2f*fTime, -0.3f*fTime );	

	m_fTexture = fTime*0.25f;

	m_bRenderText = FALSE;	

	FLOAT					fAlpha;			

	for( i = 0, fAlpha = 0.0f; i < 6 ; i++ )
		fAlpha += fSync[i];

	fAlpha = CLAMPALPHA( 0.35f*255.0f*fAlpha );

	m_piqFlash->SetAlpha( (DWORD)fAlpha );

	if( fTime > 3.0f && fTime < 15.0f )
	{
		m_bRenderText = TRUE;
		
		fAlpha = CLAMPALPHA( 255.0f*sinf( (fTime - 3.0f)*H_PI*0.1f ) );
		m_piqText[0]->SetAlpha( (DWORD)fAlpha );

		fAlpha = (fTime - 3.0f)*5.0f;
		m_piqText[0]->Resize( 490.0f - 100.0f - fAlpha, 200.0f - 30.0f - fAlpha, 490.0f + 100.0f + fAlpha, 200.0f + 30.0f + fAlpha );		

		fAlpha = CLAMPALPHA( 255.0f*sinf( (fTime - 3.5f)*H_PI*0.1f ) );
		m_piqText[1]->SetAlpha( (DWORD)fAlpha );

		fAlpha = (fTime - 3.5f)*5.0f;
		m_piqText[1]->Resize( 300.0f + fAlpha, 300.0f, 450.0f + fAlpha, 400.0f );		

		fAlpha = CLAMPALPHA( 255.0f*sinf( (fTime - 4.0f)*H_PI*0.1f ) );
		m_piqText[2]->SetAlpha( (DWORD)fAlpha );

		fAlpha = (fTime - 4.0f)*3.0f;
		m_piqText[2]->Resize( 300.0f + fAlpha, 50.0f, 450.0f + fAlpha, 150.0f );		

		fAlpha = CLAMPALPHA( 255.0f*sinf( (fTime - 4.5f)*H_PI*0.1f ) );
		m_piqText[3]->SetAlpha( (DWORD)fAlpha );

		fAlpha = (fTime - 4.5f)*2.0f;
		m_piqText[3]->Resize( 500.0f, 200.0f - fAlpha, 600.0f + 2.0f*fAlpha, 300.0f + fAlpha );		

		fAlpha = CLAMPALPHA( 255.0f*sinf( (fTime - 5.0f)*H_PI*0.15f ) );
		m_piqText[4]->SetAlpha( (DWORD)fAlpha );

		fAlpha = (fTime - 4.5f)*5.0f;
		m_piqText[4]->Resize( 450.0f - fAlpha, 100.0f - fAlpha, 500.0f + fAlpha, 200.0f + fAlpha );		
	}

	// render texture !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	m_ptrMirrors[m_dwCurrentPage^1]->SetTarget( m_pDevice );
	m_pDevice->Clear( 0, 0, D3DCLEAR_TARGET, 0xffffff, 0.0f, 0 );

	he3d_CVector			vCamPos;

	for( i = 0 ; i < 16 ; i++ )
	{	
		m_pDevice->SetViewport( &m_d3dvpMirrors[i] );		

		vCamPos = m_vPosition[i]*m_mtxMirrors;

		m_pDevice->BeginScene();

		m_pDevice->SetTransform( D3DTS_VIEW, CameraMtx( vCamPos, he3d_CVector( 0, 0, 0 ), 0 ) );	
		m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 25.0f, 1.0f, 20.0f, 1000.0f ) );	
		
		m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
		m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

		m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );		

		m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
		m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
		m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
		
		m_pDevice->SetTexture( 0, GetTexture( "fx.bmp" ) );
		m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
		m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED );	
		m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
		
		m_pDevice->SetTransform( D3DTS_TEXTURE0, ProjectionMtx( 45.0f, 0.75f, 20.0f, 1000.0f )*ZRotationMtx( m_fTexture )*TranslationMtx( 1.0f, 1.0f, 0.0f )*ScaleMtx( 0.5f, -0.5f, 1.0f ) );	

		m_pDevice->SetVertexShader( FVF_LVERTEX );

		for( DWORD i = 0 ; i < 5 ; i++ )
		{
			m_pDevice->SetTransform( D3DTS_WORLD, m_mtxRectangles[i] );
			m_pDevice->SetStreamSource( 0, m_pvbRectangles[i], sizeof(LVERTEX) );
			m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2*102 );			
		}	

		m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
		m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );		
		
		m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
		m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

		m_pDevice->SetTexture( 0, m_ptrMirrors[m_dwCurrentPage]->GetTargetTexture() );
		m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );

		m_pDevice->SetTexture( 1, GetTexture( "mirrorborder.jpg" ) );
		m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
		
		m_pDevice->SetTransform( D3DTS_WORLD, m_mtxMirrors );

		m_pDevice->SetVertexShader( FVF_LMULTITEXVERTEX );		
		m_pDevice->SetStreamSource( 0, m_pvbMirrosPod, sizeof(LMULTITEXVERTEX) );
		m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2*16 );		
		
		m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
		m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );

		m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

		m_pDevice->SetTransform( D3DTS_WORLD, IdentMtx() );

		m_psEnergy[0].SetTexture( GetTexture( "particleb.jpg" ) );
		m_psEnergy[1].SetTexture( GetTexture( "particler.jpg" ) );
		m_psEnergy[0].Render( m_pDevice );
		m_psEnergy[1].Render( m_pDevice );
		m_psEnergy[0].SetTexture( GetTexture( "particle.bmp" ) );
		m_psEnergy[1].SetTexture( GetTexture( "particle.bmp" ) );

		m_pDevice->EndScene();
	}	
	
	m_ptrMirrors[m_dwCurrentPage^1]->RestoreTarget( m_pDevice);

	m_dwCurrentPage ^=1 ;

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 45.0f, 0.75f, 20.0f, 1000.0f ) );	
	m_pDevice->SetTransform( D3DTS_VIEW, CameraMtx( he3d_CVector( 0, 0, -80 ), he3d_CVector( 0, 0, 0 ), 0 ) );	

	m_psEnergy[0].Update( fTime + 20.0f );
	m_psEnergy[1].Update( fTime + 20.0f );

	PTLMULTITEXVERTEX		pVerts;	

	if( fTime < 10.0f )
	{
		m_pvbOrnament->Lock( 0, 0, (LPBYTE*)&pVerts, 0 );
		
		*(pVerts++) = TLMULTITEXVERTEX( -1000.0f + fTime*100.0f, 480.0f, 0.0f, 0.5f, 0x0, 0.0f, 1.0f, (-1000.0f + fTime*100.0f)/640.0f, 1.00f );
		*(pVerts++) = TLMULTITEXVERTEX( -1000.0f + fTime*100.0f, 224.0f, 0.0f, 0.5f, 0x0, 0.0f, 0.0f, (-1000.0f + fTime*100.0f)/640.0f, 0.46f );
		*(pVerts++) = TLMULTITEXVERTEX(  -488.0f + fTime*100.0f, 480.0f, 0.0f, 0.5f, 0x0, 1.0f, 1.0f, ( -488.0f + fTime*100.0f)/640.0f, 1.00f );
		*(pVerts++) = TLMULTITEXVERTEX(  -488.0f + fTime*100.0f, 224.0f, 0.0f, 0.5f, 0x0, 1.0f, 0.0f, ( -488.0f + fTime*100.0f)/640.0f, 0.46f );

		m_pvbOrnament->Unlock();
	}

	m_bRenderFade = FALSE;

	if( fTime < 2.0f )
	{
		m_bRenderFade = TRUE;

		fAlpha = CLAMPALPHA( ( 2.0f - fTime )*255.0f );
		m_piqFade->SetAlpha( (DWORD)fAlpha );
	}
	else if( fTime > 20.5f )
	{
		m_bRenderFade = TRUE;

		fAlpha = CLAMPALPHA( ( fTime - 20.5f )*255.0f );
		m_piqFade->SetAlpha( (DWORD)fAlpha );
	}

	return TRUE;
}

BOOL CMirrors::RenderEfx()
{
	m_pDevice->Clear( 0, 0, D3DCLEAR_TARGET, 0xffffff, 0.0f, 0 );

	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );	

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

	m_pDevice->SetTexture( 0, GetTexture( "triangle.bmp" ) );	

	m_pDevice->SetStreamSource( 0, m_pvbTrinagles, sizeof(LVERTEX) );
	m_pDevice->SetVertexShader( FVF_LVERTEX );

	for( DWORD i = 1 ; i < 5 ; i++ )
	{	
		m_pDevice->SetTransform( D3DTS_WORLD, m_mtxTriangles[i] );
		m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 5 );
	}	

	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );		
	
	m_pDevice->SetTexture( 0, GetTexture( "fx.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED );	
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
	
	m_pDevice->SetTransform( D3DTS_TEXTURE0, ProjectionMtx( 45.0f, 0.75f, 20.0f, 1000.0f )*ZRotationMtx( m_fTexture )*TranslationMtx( 1.0f, 1.0f, 0.0f )*ScaleMtx( 0.5f, -0.5f, 1.0f ) );	

	m_pDevice->SetVertexShader( FVF_LVERTEX );

	for( i = 0 ; i < 5 ; i++ )
	{
		m_pDevice->SetTransform( D3DTS_WORLD, m_mtxRectangles[i]*TranslationMtx( 20, -10, 0 ) );
		m_pDevice->SetStreamSource( 0, m_pvbRectangles[i], sizeof(LVERTEX) );
		m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2*102 );
	}	
	
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );		

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

	m_pDevice->SetTexture( 0, m_ptrMirrors[m_dwCurrentPage]->GetTargetTexture() );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );

	m_pDevice->SetTexture( 1, GetTexture( "mirrorborder.jpg" ) );
	m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
	
	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxMirrors*TranslationMtx( 20, -10, 0 ) );

	m_pDevice->SetVertexShader( FVF_LMULTITEXVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbMirrosPod, sizeof(LMULTITEXVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2*16 );
	
	m_pDevice->SetTexture( 1, NULL );		
	m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );

	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

	m_pDevice->SetTransform( D3DTS_WORLD, TranslationMtx( 20, -10, 0 ) );
	m_psEnergy[0].Render( m_pDevice );
	m_psEnergy[1].Render( m_pDevice );

	m_pDevice->SetTexture( 0, GetTexture( "mirrorback.jpg" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 );	
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );

	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );

	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxMirrors*TranslationMtx( 20, -10, 0 ) );

	m_pDevice->SetVertexShader( FVF_LMULTITEXVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbMirrosPod, sizeof(LMULTITEXVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2*16 );

	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );	

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
	
	m_pDevice->SetTexture( 0, GetTexture( "fx.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED );	
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
	
	m_pDevice->SetTransform( D3DTS_TEXTURE0, ProjectionMtx( 45.0f, 0.75f, 20.0f, 1000.0f )*ZRotationMtx( m_fTexture )*TranslationMtx( 1.0f, 1.0f, 0.0f )*ScaleMtx( 0.5f, -0.5f, 1.0f ) );	

	m_pDevice->SetVertexShader( FVF_LVERTEX );

	for( i = 0 ; i < 5 ; i++ )
	{
		m_pDevice->SetTransform( D3DTS_WORLD, m_mtxRectangles[i]*TranslationMtx( 20, -10, 0 ) );
		m_pDevice->SetStreamSource( 0, m_pvbRectangles[i], sizeof(LVERTEX) );
		m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2*102 );
	}	

	m_pDevice->SetTexture( 0, NULL );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );		
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

	if( m_bRenderText )
	{		
		m_pDevice->SetTexture( 0, GetTexture( "text.bmp" ) );
		m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );

		for( i = 0 ; i < 5 ; i++ )
			m_piqText[i]->Render( m_pDevice );

		m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	}

	m_pDevice->SetTexture( 0, GetTexture( "alphamask.bmp" ) );
	m_piqMask->Render( m_pDevice );
	
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );	

	m_pDevice->SetTexture( 0, GetTexture( "ornament.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	m_pDevice->SetTexture( 1, GetTexture( "alphamask.bmp" ) );
	m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
	m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE );

	m_pDevice->SetVertexShader( FVF_TLMULTITEXVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbOrnament, sizeof(TLMULTITEXVERTEX) );

	m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE);

	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
	m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
	m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SUBTRACT );
	m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT );
	m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE );

	m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
	m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
	m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
	m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );	

	m_pDevice->SetTexture( 0, NULL );
	m_pDevice->SetTexture( 1, NULL );

	m_piqFlash->Render( m_pDevice );

	if( m_bRenderFade )
		m_piqFade->Render( m_pDevice );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	
	return TRUE;
}

